﻿using XAMLStylePad.Models;
using System.Diagnostics;
using Microsoft.Win32;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections;
using FireFly;

namespace XAMLStylePad.ViewModels
{
    [DebuggerDisplay("{DisplayName}({Sources.Count})")]
    public class ProjectViewModel : XamlViewModelBase<ProjectBase>
    {
        public ProjectViewModel(ProjectBase project)
            : base(project)
        {
        }

        #region Name
        public string Name
        {
            get
            {
                return Model.Name;
            }
            set
            {
                Model.Name = value;
                OnPropertyChanged("Name");
            }
        }
        #endregion

        #region Directory
        public string Directory
        {
            get
            {
                return Model.Directory;
            }
            set
            {
                Model.Directory = value;
                OnPropertyChanged("Directory");
            }
        }
        #endregion

        #region FullPath
        public string FullPath
        {
            get
            {
                return Model.FullPath;
            }
            set
            {
                Model.FullPath = value;
                OnPropertyChanged("FullPath");
            }
        }
        #endregion

        #region src
        public CollectionViewModel<SourceBase, SourceViewModel> src
        {
            get
            {
                if(_src == null)
                {
                    _src = new CollectionViewModel<SourceBase, SourceViewModel>(Model.Sources, "src", CollectionShowMode.AlwaysShow, model =>
                    {
                        var viewModel = new SourceViewModel(model);

                        return viewModel;
                    }) { Parent = this };
                }
                return _src;
            }
        }
        CollectionViewModel<SourceBase, SourceViewModel> _src;
        #endregion



        #region Sources
        public CollectionViewModel<SourceBase, SourceViewModel> Sources
        {
            get
            {
                if(_Sources == null)
                {
                    _Sources = new CollectionViewModel<SourceBase, SourceViewModel>(Model.Sources, o => new SourceViewModel(o))
                    {
                        DisplayName = "Sources",
                        Parent = this
                    };
                }
                return _Sources;
            }
        }

        CollectionViewModel<SourceBase, SourceViewModel> _Sources;
        #endregion

        #region IsReadOnly
        public override bool IsReadOnly
        {
            get
            {
                return Model.IsReadOnly;
            }
        }
        #endregion

        #region overrides
        public override string DisplayName
        {
            get
            {
                return Name ?? "New Project";
            }
        }

        public override IEnumerable<IRelayCommand> Commands
        {
            get
            {
                return new IRelayCommand[]
                {
                    SaveCommand,
                    SaveAsCommand,
                    //LoadCommand,
                    AddXAMLSourceCommand,
                    AddAssemblySourceCommand
                };
            }
        }
        #endregion

        //Commands

        #region SaveCommand
        public static IRelayCommand SaveCommand { get { return _SaveCommand; } }
        static RelayCommand<ProjectViewModel> _SaveCommand = new EditCommand<ProjectViewModel>(context =>
        {
            var vm = context.ViewModel;
            if(!vm.IsReadOnly)
            {
                if(vm.FullPath != null)
                    vm.Model.Save(context.ViewModel.Model.FullPath);
                else
                    SaveAsCommand.Execute(context);
            }
        }, "ProjectViewModel.SaveCommand");
        #endregion

 
        #region SaveAsCommand
        public static IRelayCommand SaveAsCommand { get { return _SaveAsCommand; } }
        static RelayCommand<ProjectViewModel> _SaveAsCommand = new EditCommand<ProjectViewModel>(context =>
        {
            SaveFileDialog dlg = new SaveFileDialog()
            {
                Filter = "XAMLStylePad project files(*.spp)|*.spp",
                OverwritePrompt = true,
                InitialDirectory = Environment.CurrentDirectory
            };
            dlg.OverwritePrompt = true;
            if(dlg.ShowDialog() == true)
            {
                context.ViewModel.Model.FullPath = dlg.FileName;
                context.ViewModel.Model.Save(dlg.FileName);
            }
        }, "ProjectViewModel.SaveAsCommand");
        #endregion

        #region AddAssemblyCommand
        public static IRelayCommand AddAssemblySourceCommand { get { return _AddAssemblySourceCommand; } }
        static RelayCommand<ProjectViewModel> _AddAssemblySourceCommand = new RelayCommand<ProjectViewModel>(context =>
        {
            var dlg = new OpenFileDialog()
            {
                InitialDirectory = Environment.CurrentDirectory,
                Filter = "Assemblies and executes(*.dll, *.exe)|*.dll;*.exe",
                CheckPathExists = true,
                Multiselect = true
            };

            if(dlg.ShowDialog() == true)
            {
                context.ViewModel.CreateSources(dlg.FileNames, f => new AssemblySource(f));
            }
        },
        context => 
            context != null && context.ViewModel != null,

        "ProjectViewModel.AddAssemblySourceCommand");
        #endregion

        private void CreateSources(string[] fileNames, Func<string, SourceBase> generator)
        {
            var list = from f in fileNames
                       where !this.Sources.Select(s => s.FullPath).Contains(f)
                       select new SourceViewModel(generator(f));

            foreach(var source in list)
            {
                this.Sources.Add(source);
            }
        }

        #region AddXAMLSourceCommand
        public static IRelayCommand AddXAMLSourceCommand { get { return _AddXAMLSourceCommand; } }
        static RelayCommand<ProjectViewModel> _AddXAMLSourceCommand = new RelayCommand<ProjectViewModel>(context =>
        {
            OpenFileDialog dlg = new OpenFileDialog()
            {
                Filter = "XAML files(*.xaml; *.xoml)|*.xaml;*.xoml",
                CheckFileExists = true,
                DefaultExt = "*.xaml",
                Multiselect = true
            };

            if(dlg.ShowDialog() == true)
            {
                context.ViewModel.CreateSources(dlg.FileNames, f => new XamlSource(f));
            }
        },
        context => 
            context != null && context.ViewModel != null,
        "ProjectViewModel.AddXAMLSourceCommand");
        #endregion

        //#region Rename
        //public static RelayCommand<ProjectViewModel> Rename
        //{
        //    get
        //    {
        //        if(_Rename == null)
        //        {
        //            _Rename = new RelayCommand<ProjectViewModel>(context =>
        //            {
        //                var name = 
        //                context.ViewModels.Name = name;
        //            }, "ProjectViewModel.Rename");
        //        }
        //        return _Rename;
        //    }
        //}
        //static RelayCommand<ProjectViewModel> _Rename;
        //#endregion

        public virtual bool IsChanged
        {
            get
            {
                return _IsChanged;
            }
        }
        bool _IsChanged = false;

        public void Close()
        {
            if(IsChanged)
            {
                Model.Save(Model.FullPath);
            }
        }

        public override ICollection VisualChildren
        {
            get
            {
                return Sources;
            }
        }
    }
}